#include "Application.h"
#include "StoneEntity.h"
#include "PacmanEntity.h"
#include "GhostEntity.h"
#include "AppleEntity.h"
#include <iostream>

Application::Application(void) : _Level(NULL)
{}

Application::~Application(void)
{
	//Delete level
	if(_Level != NULL) delete _Level;
}

/// Initialization the application
/// Must be invoked before launching the application!!!
void Application::Initialize()
{
	//Load images
	_ImageManager.LoadImages();

	_Level = _ConfigurationManager.CreateLevel("../Data/LevelTest.lvl");

	//Create window
	_RenderWindow.Create(sf::VideoMode(800, 600, 32), "Pacman", sf::Style::Close);

	//Initialize application properties
	_FrameRate = 40;
	_ThinkRate = 1;
}


/// Starts the application
void Application::Run()
{
	//Initialize Clock
	_Clock.Reset();
	std::cout<<"Application started"<<std::endl;
	_EventManager.ResetInput();
	_EventManager.RequestRefreshAllWindow();
	_Level->DrawAll(_RenderWindow);
	_RenderWindow.Display();
	

	//Main loop
	do
	{
		//Retrieve inputs
		_EventManager.UpdateInput(_RenderWindow);

		//Check time ellapsed
		int vNbThinkToDo = _ThinkRate;
		float vFrameTime = _Clock.GetElapsedTime();

		if(vFrameTime >= 1/_FrameRate) //The iteration is late
		{
			_Clock.Reset();
			vNbThinkToDo *= (int)(vFrameTime * _FrameRate);

			//Frame iteration info
			std::cout<<"##Time Ellapsed: "<< vFrameTime << "## The iteration is late!!" <<std::endl;
		}
		else //The iteration is on time
		{
			float vTowait = 1/_FrameRate - vFrameTime;
			sf::Sleep(vTowait);
			_Clock.Reset();

			//Frame iteration info
			//std::cout<<"##Time Ellapsed: "<< vFrameTime << "## Wait: " << vTowait << std::endl;
		}

		//Think
		for(; vNbThinkToDo>0; vNbThinkToDo--) 
			_Level->Think();

		//Draw
		if(!_EventManager.IsRefreshAllWindowRequested())
		{
			_Level->Draw(_RenderWindow);
		}
		else
		{
			_Level->DrawAll(_RenderWindow);
			_EventManager.ResetWindowRefreshRequest();
			std::cout<<"Window refreshed!"<<std::endl;
		}
		_RenderWindow.Display();

	}
	while(_RenderWindow.IsOpened());

	std::cout<<"Application ended"<<std::endl;
}